package model

import (
	"context"
	"ginblog/utils"
	"ginblog/utils/errmsg"
	"github.com/qiniu/go-sdk/v7/auth/qbox"
	"github.com/qiniu/go-sdk/v7/storage"
	"mime/multipart"
)

var Zone = utils.Zone
var AccessKey = utils.AccessKey
var SecretKey = utils.SecretKey
var Bucket = utils.Bucket
var ImgUrl = utils.QiniuSever

// UpLoadFile 上传文件函数
// UpLoadFile 上传文件到指定的存储空间
// 参数:
//
//	file: 类型为multipart.File的文件对象，通常来自HTTP请求
//	fileSize: 文件大小，用于验证和上传过程
//
// 返回值:
//
//	string: 上传成功后的文件URL
//	int: 错误码，表示上传是否成功
func UpLoadFile(file multipart.File, fileSize int64) (string, int) {
	// 创建上传策略，指定文件上传的范围（Bucket）
	putPolicy := storage.PutPolicy{
		Scope: Bucket,
	}
	// 创建Mac对象，用于生成上传凭证
	mac := qbox.NewMac(AccessKey, SecretKey)
	// 生成上传凭证
	upToken := putPolicy.UploadToken(mac)

	// 配置上传所需的配置信息
	cfg := setConfig()

	// 初始化上传的额外选项
	putExtra := storage.PutExtra{}

	// 创建表单上传器
	formUploader := storage.NewFormUploader(&cfg)
	// 初始化上传返回的结果对象
	ret := storage.PutRet{}

	// 执行文件上传操作，不需要指定文件名
	err := formUploader.PutWithoutKey(context.Background(), &ret, upToken, file, fileSize, &putExtra)
	if err != nil {
		// 如果上传出错，返回空字符串和错误码
		return "", errmsg.ERROR
	}
	// 拼接文件的完整URL
	url := ImgUrl + ret.Key
	// 返回文件URL和成功码
	return url, errmsg.SUCCESS
}

// setConfig 配置存储服务的设置。
// 该函数无需参数。
// 返回值是 storage.Config 类型，用于配置存储服务的各种选项。
// 该函数主要负责初始化存储服务的配置，包括选择区域、是否使用CDN域名和是否使用HTTPS。
// 选择区域是通过调用 selectZone 函数来实现的。
// 目前不使用CDN域名和HTTPS，因此这两项配置都设置为 false。
func setConfig() storage.Config {
	cfg := storage.Config{
		Zone:          selectZone(Zone),
		UseCdnDomains: false,
		UseHTTPS:      false,
	}
	return cfg
}

// selectZone 根据ID选择对应的存储区域。
// 参数:
//
//	id - 存储区域的ID，用于确定返回哪个存储区域。
//
// 返回值:
//
//	*storage.Zone - 返回一个指向storage包中Zone类型的指针，表示选定的存储区域。
//
// 该函数根据提供的ID选择一个存储区域。如果ID不匹配任何预定义的存储区域，则默认返回华东区域。
func selectZone(id int) *storage.Zone {
	switch id {
	case 1:
		return &storage.ZoneHuadong
	case 2:
		return &storage.ZoneHuabei
	case 3:
		return &storage.ZoneHuanan
	default:
		return &storage.ZoneHuadong
	}
}
